/**
 * 下载管理器 - 图片视频下载器
 * 负责处理文件下载、队列管理、进度跟踪等功能
 */

/**
 * 下载管理器类
 */
export class DownloadManager {
    constructor() {
        this.downloadQueue = new Map();
        this.activeDownloads = new Set();
        this.maxConcurrent = 3;
        this.settings = {};
    }

    /**
     * 初始化下载管理器
     */
    async init(settings = {}) {
        this.settings = {
            maxConcurrent: 3,
            maxFileSize: 100 * 1024 * 1024, // 100MB
            downloadPath: 'downloads',
            filenamePattern: '{filename}',
            ...settings
        };

        this.maxConcurrent = this.settings.maxConcurrent;

        console.log('下载管理器初始化完成');
    }

    /**
     * 下载文件
     * @param {Array} files - 要下载的文件列表
     * @param {Object} settings - 下载设置
     * @returns {Promise<Array>} 下载结果
     */
    async downloadFiles(files, settings = {}) {
        const downloadSettings = { ...this.settings, ...settings };
        const results = [];

        console.log(`开始下载 ${files.length} 个文件...`);

        for (const file of files) {
            try {
                // 验证文件
                const validation = this.validateFile(file, downloadSettings);
                if (!validation.valid) {
                    results.push({
                        id: file.id,
                        success: false,
                        error: validation.error
                    });
                    continue;
                }

                // 生成文件名
                const filename = this.generateFilename(file, downloadSettings);

                // 添加到下载队列
                const downloadItem = {
                    id: file.id,
                    url: file.url,
                    filename: filename,
                    type: file.type,
                    size: file.size || 0,
                    state: 'pending',
                    progress: 0,
                    startTime: Date.now(),
                    settings: downloadSettings
                };

                this.downloadQueue.set(file.id, downloadItem);
                results.push({
                    id: file.id,
                    success: true,
                    downloadItem: downloadItem
                });

                // 开始下载
                this.processDownloadQueue();

            } catch (error) {
                console.error(`下载文件失败: ${file.url}`, error);
                results.push({
                    id: file.id,
                    success: false,
                    error: error.message
                });
            }
        }

        return results;
    }

    /**
     * 验证文件
     */
    validateFile(file, settings) {
        // 检查URL
        if (!file.url || !file.url.startsWith('http')) {
            return { valid: false, error: '无效的URL' };
        }

        // 检查文件大小
        if (file.size && file.size > settings.maxFileSize) {
            return { valid: false, error: '文件过大' };
        }

        // 检查文件类型
        const allowedTypes = ['image', 'video'];
        if (!allowedTypes.includes(file.type)) {
            return { valid: false, error: '不支持的文件类型' };
        }

        return { valid: true };
    }

    /**
     * 生成文件名
     */
    generateFilename(file, settings) {
        let filename = settings.filenamePattern;

        // 替换模板变量
        filename = filename.replace('{filename}', file.filename || 'unknown');
        filename = filename.replace('{title}', file.title || '');
        filename = filename.replace('{type}', file.type);
        filename = filename.replace('{timestamp}', Date.now());

        // 清理文件名
        filename = this.sanitizeFilename(filename);

        // 确保有扩展名
        if (!filename.includes('.')) {
            const extension = this.getFileExtension(file.url);
            filename += `.${extension}`;
        }

        return filename;
    }

    /**
     * 清理文件名
     */
    sanitizeFilename(filename) {
        // 移除或替换非法字符
        return filename
            .replace(/[<>:"/\\|?*]/g, '_')
            .replace(/\s+/g, '_')
            .replace(/_{2,}/g, '_')
            .trim();
    }

    /**
     * 获取文件扩展名
     */
    getFileExtension(url) {
        try {
            const urlObj = new URL(url);
            const pathname = urlObj.pathname;
            const match = pathname.match(/\.([^.]+)$/);

            if (match) {
                return match[1].toLowerCase();
            }

            // 根据URL推断扩展名
            if (url.includes('image/')) {
                return 'jpg';
            }
            if (url.includes('video/')) {
                return 'mp4';
            }

            return 'unknown';
        } catch (error) {
            return 'unknown';
        }
    }

    /**
     * 处理下载队列
     */
    async processDownloadQueue() {
        // 检查是否有可用的下载槽
        if (this.activeDownloads.size >= this.maxConcurrent) {
            return;
        }

        // 查找待下载的项目
        for (const [id, item] of this.downloadQueue) {
            if (item.state === 'pending' && !this.activeDownloads.has(id)) {
                this.startDownload(item);
                break;
            }
        }
    }

    /**
     * 开始下载
     */
    async startDownload(item) {
        try {
            console.log(`开始下载: ${item.filename}`);

            this.activeDownloads.add(item.id);
            item.state = 'in_progress';
            item.startTime = Date.now();

            // 使用Chrome Downloads API下载文件
            const downloadId = await chrome.downloads.download({
                url: item.url,
                filename: `${item.settings.downloadPath}/${item.filename}`,
                saveAs: false,
                conflictAction: 'uniquify'
            });

            // 保存下载ID
            item.downloadId = downloadId;

            // 监听下载进度
            this.monitorDownload(item);

        } catch (error) {
            console.error(`下载失败: ${item.filename}`, error);
            item.state = 'error';
            item.error = error.message;
            this.activeDownloads.delete(item.id);
            this.processDownloadQueue();
        }
    }

    /**
     * 监控下载进度
     */
    monitorDownload(item) {
        const checkProgress = () => {
            if (item.state === 'cancelled') {
                return;
            }

            chrome.downloads.search({ id: item.downloadId }, (downloads) => {
                if (downloads.length > 0) {
                    const download = downloads[0];

                    // 更新状态
                    item.state = download.state;
                    item.progress = download.bytesReceived / download.fileSize * 100 || 0;

                    // 处理完成状态
                    if (download.state === 'complete') {
                        this.onDownloadComplete(item);
                    } else if (download.state === 'interrupted') {
                        this.onDownloadError(item, download.error);
                    }
                }
            });
        };

        // 定期检查进度
        const progressInterval = setInterval(checkProgress, 1000);

        // 保存间隔ID以便清理
        item.progressInterval = progressInterval;
    }

    /**
     * 下载完成处理
     */
    onDownloadComplete(item) {
        console.log(`下载完成: ${item.filename}`);

        item.state = 'complete';
        item.progress = 100;
        item.endTime = Date.now();

        // 清理资源
        this.cleanupDownload(item);

        // 处理队列中的下一个
        this.processDownloadQueue();
    }

    /**
     * 下载错误处理
     */
    onDownloadError(item, error) {
        console.error(`下载错误: ${item.filename}`, error);

        item.state = 'error';
        item.error = error;

        // 清理资源
        this.cleanupDownload(item);

        // 处理队列中的下一个
        this.processDownloadQueue();
    }

    /**
     * 清理下载资源
     */
    cleanupDownload(item) {
        this.activeDownloads.delete(item.id);

        if (item.progressInterval) {
            clearInterval(item.progressInterval);
            delete item.progressInterval;
        }
    }

    /**
     * 暂停下载
     */
    async pauseDownload(downloadId) {
        try {
            const item = this.downloadQueue.get(downloadId);
            if (!item || item.state !== 'in_progress') {
                throw new Error('下载项不存在或状态不正确');
            }

            await chrome.downloads.pause(downloadId);
            item.state = 'paused';

            console.log(`下载已暂停: ${item.filename}`);

        } catch (error) {
            console.error('暂停下载失败:', error);
            throw error;
        }
    }

    /**
     * 恢复下载
     */
    async resumeDownload(downloadId) {
        try {
            const item = this.downloadQueue.get(downloadId);
            if (!item || item.state !== 'paused') {
                throw new Error('下载项不存在或状态不正确');
            }

            await chrome.downloads.resume(downloadId);
            item.state = 'in_progress';

            console.log(`下载已恢复: ${item.filename}`);

        } catch (error) {
            console.error('恢复下载失败:', error);
            throw error;
        }
    }

    /**
     * 取消下载
     */
    async cancelDownload(downloadId) {
        try {
            const item = this.downloadQueue.get(downloadId);
            if (!item) {
                throw new Error('下载项不存在');
            }

            if (item.downloadId) {
                await chrome.downloads.cancel(item.downloadId);
            }

            item.state = 'cancelled';
            this.cleanupDownload(item);
            this.downloadQueue.delete(downloadId);

            console.log(`下载已取消: ${item.filename}`);

        } catch (error) {
            console.error('取消下载失败:', error);
            throw error;
        }
    }

    /**
     * 更新下载状态
     */
    updateDownloadStatus(downloadId, state) {
        const item = this.downloadQueue.get(downloadId);
        if (item) {
            item.state = state;
        }
    }

    /**
     * 获取下载队列状态
     */
    getQueueStatus() {
        const status = {
            total: this.downloadQueue.size,
            active: this.activeDownloads.size,
            pending: 0,
            completed: 0,
            error: 0,
            paused: 0
        };

        for (const item of this.downloadQueue.values()) {
            switch (item.state) {
                case 'pending':
                    status.pending++;
                    break;
                case 'complete':
                    status.completed++;
                    break;
                case 'error':
                    status.error++;
                    break;
                case 'paused':
                    status.paused++;
                    break;
            }
        }

        return status;
    }

    /**
     * 清空下载队列
     */
    async clearQueue() {
        const promises = [];

        for (const [id, item] of this.downloadQueue) {
            if (item.state === 'in_progress') {
                promises.push(this.cancelDownload(id));
            }
        }

        await Promise.all(promises);
        this.downloadQueue.clear();
        this.activeDownloads.clear();

        console.log('下载队列已清空');
    }

    /**
     * 获取下载项信息
     */
    getDownloadItem(downloadId) {
        return this.downloadQueue.get(downloadId);
    }

    /**
     * 获取所有下载项
     */
    getAllDownloads() {
        return Array.from(this.downloadQueue.values());
    }

    /**
     * 批量下载处理
     */
    async batchDownload(files, settings = {}) {
        const batchId = `batch_${Date.now()}`;
        const results = [];

        console.log(`开始批量下载: ${files.length} 个文件`);

        // 分批处理，避免同时下载过多文件
        const batchSize = settings.batchSize || 5;
        const batches = this.chunkArray(files, batchSize);

        for (let i = 0; i < batches.length; i++) {
            const batch = batches[i];
            console.log(`处理批次 ${i + 1}/${batches.length}: ${batch.length} 个文件`);

            const batchResults = await this.downloadFiles(batch, settings);
            results.push(...batchResults);

            // 等待一段时间再处理下一批
            if (i < batches.length - 1) {
                await this.delay(1000);
            }
        }

        console.log(`批量下载完成: ${results.length} 个文件`);
        return results;
    }

    /**
     * 数组分块
     */
    chunkArray(array, size) {
        const chunks = [];
        for (let i = 0; i < array.length; i += size) {
            chunks.push(array.slice(i, i + size));
        }
        return chunks;
    }

    /**
     * 延迟函数
     */
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * 销毁下载管理器
     */
    destroy() {
        this.clearQueue();
        console.log('下载管理器已销毁');
    }
} 